#include "biometricswidget.h"
#include "ui_biometricswidget.h"
#include <QDBusInterface>
#include <QDBusConnection>
#include <QDBusError>
#include <QDBusReply>
#include <QDBusArgument>
#include <QDBusMetaType>
#include <QProcess>
#include <QDBusMessage>
#include <QDBusObjectPath>
#include <QToolButton>
#include <QMenu>
#include <QDebug>
#include <QDBusInterface>
#include <QLineEdit>
#include <QMessageBox>
#include <unistd.h>
#include <ukcc/widgets/switchbutton.h>
#include <ukcc/widgets/imageutil.h>
#include "namelabel.h"
#include "changefeaturename.h"
#include "elipsemaskwidget.h"
#include "passwdcheckutil.h"
#include "changeuserpwd.h"
#include "servicemanager.h"
#include <polkit-qt5-1/polkitqt1-authority.h>
#include <glib.h>
#define DEFAULTFACE "/usr/share/ukui/faces/default.png"

#define ITEMHEIGH 61
BiometricsWidget::BiometricsWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::BiometricsWidget)
    , m_strBoundWechat("")
{
    ui->setupUi(this);
    initBioComonent();
}

BiometricsWidget::~BiometricsWidget()
{
    delete ui;
}

void BiometricsWidget::initBioComonent()
{
    m_biometricProxy = new BiometricProxy(this);
    initSearchText();
    ui->enableBiometricFrame->setFrameShape(QFrame::NoFrame);
    ui->biometricTypeFrame->setFrameShape(QFrame::NoFrame);
    ui->biometricDeviceFrame->setFrameShape(QFrame::NoFrame);
    ui->enableBiometricFrame->setStyleSheet("QFrame{background: palette(base);\
                                                border-top-left-radius: 4px;border-top-right-radius: 4px;}");
    ui->biometricDeviceFrame->setStyleSheet("QFrame{background: palette(base);border-top-right-radius: 4px;}");
    ui->biometricTypeFrame->setStyleSheet("QFrame{background: palette(base);border-top-right-radius: 4px;}");
    serviceInterface = new QDBusInterface(DBUS_SERVICE,
                                          DBUS_PATH,
                                          DBUS_INTERFACE
                                          , QDBusConnection::systemBus());
    serviceInterface->setTimeout(2147483647); /* 微秒 */


    addBioFeatureBtn = new EnrollBtn;
    addUserHorLayout = new QHBoxLayout();
    addUserHorLayout->setSpacing(8);
    addUserHorLayout->setContentsMargins(0, 0, 0, 0);
    addUserHorLayout->addWidget(addBioFeatureBtn);

    addUserFrame = new QFrame();
    addUserFrame->setObjectName("continue");
    addUserFrame->setMinimumSize(QSize(550, 60));
    addUserFrame->setMaximumSize(QSize(16777215, 60));
    addUserFrame->setFrameShape(QFrame::NoFrame);
    addUserFrame->setLayout(addUserHorLayout);

//    addBioFeatureBtn->setProperty("useIconHighlightEffect", true);
//    addBioFeatureBtn->setProperty("useIconHighlightEffect", 0x2);
    connect(addBioFeatureBtn, &EnrollBtn::clicked, [=] {
        showEnrollDialog();
    });
    ui->addFeatureLayout->addWidget(addUserFrame);

    ui->bioFeatureListWidget->setStyleSheet("QListWidget{border-radius:0px;};\
                                            QListWidget::Item:hover{background:palette(base);border-radius:0px;}");
    ui->bioFeatureListWidget->setSpacing(0);

    ui->bioFeatureListWidget->setFixedHeight(biometricFeatureMap.count()*ITEMHEIGH + 1);

    connect(ui->biometrictypeBox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(onbiometricTypeBoxCurrentIndexChanged(int)));

    connect(ui->biometricDeviceBox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(onbiometricDeviceBoxCurrentIndexChanged(int)));

    ui->toolButton->setStyleSheet("QToolButton{background-color: palette(base);}");
    ui->toolButton->setIcon(QIcon::fromTheme("view-more-horizontal-symbolic"));
    menu = new QMenu();
    QAction *installAction = new QAction(tr("Advanced Settings"), this);
    connect(installAction, &QAction::triggered, this, [&]{
        QProcess process(this);
        process.startDetached("/usr/bin/biometric-manager");
    });
    menu->addActions({installAction});
    ui->toolButton->setPopupMode(QToolButton::InstantPopup);
    ui->toolButton->setMenu(menu);

    updateDevice();
    onbiometricDeviceBoxCurrentIndexChanged(ui->biometricDeviceBox->currentIndex());

    if(m_biometricProxy && m_biometricProxy->isValid())
    {
        connect(m_biometricProxy, &BiometricProxy::USBDeviceHotPlug,
            this, &BiometricsWidget::onBiometricUSBDeviceHotPlug);

        connect(m_biometricProxy, &BiometricProxy::FeatureChanged,
                this, &BiometricsWidget::onFeatureChanged);
    }
    ServiceManager *sm = ServiceManager::instance();
    connect(sm, &ServiceManager::serviceStatusChanged,
            this, &BiometricsWidget::onBiometricServiceStatus);

    ui->qrCodeLoginlabel2->setStyleSheet("color: #818181;");
    ui->enableBiometricLabel2->setStyleSheet("color: #818181;");

    QString strDisplay1=ui->enableBiometricLabel2->text();
    QString text1 = ui->enableBiometricLabel2->text();
    QFontMetrics font1(strDisplay1);
    int font_size1 = font1.width(strDisplay1);
    if(font_size1 > 200)
    {
        //返回字符串末尾带省略号的字符串
        ui->enableBiometricLabel2->setToolTip(strDisplay1);
        strDisplay1 = font1.elidedText(text1, Qt::ElideMiddle, 195);
    }
    ui->enableBiometricLabel2->setText(strDisplay1);

    enableBiometricBtn = new KSwitchButton(ui->enableBiometricFrame);

    mBiometricWatcher = nullptr;
    initDashboardBioAuthSection();
    enableBiometricBtn->setChecked(getBioStatus());
    ui->enableBiometricLayout->addWidget(enableBiometricBtn);
    connect(enableBiometricBtn, &KSwitchButton::stateChanged, [=](bool checked){
        QProcess process;
        if(checked){
            process.start("bioctl enable");
            process.waitForFinished(3000);
            setBiometricDeviceVisible(true);
        }else{
            process.start("bioctl disable");
            process.waitForFinished(3000);
            setBiometricDeviceVisible(false);
        }   
    });

    connect(ui->changePasswordPB_3, &QPushButton::clicked, this, [=](bool checked){
        Q_UNUSED(checked)
        showChangePwdDialog();
    });
    initUserInfo();

    connect(ui->bindOrUnbindBtn, &QToolButton::clicked, this, [=]() {
        if (getCurUserQRCodeAcount().isEmpty()) {
            showQRCodeScanDialog();
        } else {
            m_biometricProxy->deleteFeature(DRIVEID_WECHAT,getuid(),0,-1);
            QTimer::singleShot(0, this, [&,this](){
                Q_EMIT this->updateQRCodeInfo();
            });
        }
    });
    connect(this, &BiometricsWidget::updateQRCodeInfo, this, &BiometricsWidget::onUpdateQRCodeInfo);
    connect(this, &BiometricsWidget::updateFunctionsWidget, this, &BiometricsWidget::onUpdateFunctionsWidget);
    QTimer::singleShot(0, this, [&,this](){
        Q_EMIT this->updateQRCodeInfo();
    });
    readConfigures();
}

void BiometricsWidget::initDashboardBioAuthSection()
{
    QProcess process;
    process.start("bioctl status");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();
    qDebug() << "bioctl status ---" << output;
    if (output.contains("enable", Qt::CaseInsensitive)) {
        setBiometricDeviceVisible(true);
    }
    else {
        setBiometricDeviceVisible(false);
    }

    if(!mBiometricWatcher){
        mBiometricWatcher = new QFileSystemWatcher(this);
        mBiometricWatcher->addPath(UKUI_BIOMETRIC_SYS_CONFIG_PATH);
        connect(mBiometricWatcher,&QFileSystemWatcher::fileChanged,this,[=](const QString &path){
            mBiometricWatcher->addPath(UKUI_BIOMETRIC_SYS_CONFIG_PATH);
            initDashboardBioAuthSection();
            enableBiometricBtn->blockSignals(true);
            enableBiometricBtn->setChecked(getBioStatus());
            enableBiometricBtn->blockSignals(false);
            readConfigures();
        });
    }
}

void BiometricsWidget::initUserInfo()
{
    QDBusInterface iface("org.freedesktop.Accounts", "/org/freedesktop/Accounts",
                         "org.freedesktop.Accounts",QDBusConnection::systemBus());

    QDBusReply<QDBusObjectPath> userPath = iface.call("FindUserById", (qint64)getuid());
    if(!userPath.isValid())
        qWarning() << "Get UserPath error:" << userPath.error();
    else {
        m_user.current = true;
        m_user.logined = false;
        m_user.autologin = false;

        QString path = userPath.value().path();
        QDBusInterface iproperty("org.freedesktop.Accounts",
                                 path,
                                 "org.freedesktop.DBus.Properties",
                                 QDBusConnection::systemBus());
        QDBusReply<QMap<QString, QVariant> > reply = iproperty.call("GetAll", "org.freedesktop.Accounts.User");
        if (reply.isValid()){
            QMap<QString, QVariant> propertyMap;
            propertyMap = reply.value();
            m_user.username = propertyMap.find("UserName").value().toString();
            m_user.realname = propertyMap.find("RealName").value().toString();

            if (m_user.realname.isEmpty()){
                m_user.realname = propertyMap.find("UserName").value().toString();
            }

            if (m_user.username == QString(g_get_user_name())) {
                m_user.current = true;
                m_user.logined = true;
                m_user.noPwdLogin = false;
            }
            m_user.accounttype = propertyMap.find("AccountType").value().toInt();
            m_user.iconfile = propertyMap.find("IconFile").value().toString();
            if(m_user.iconfile.isEmpty()){
                m_user.iconfile = DEFAULTFACE;
            }
            char * iconpath = m_user.iconfile.toLatin1().data();
            if (!g_file_test(iconpath, G_FILE_TEST_EXISTS)){
                m_user.iconfile = DEFAULTFACE;
            }

            m_user.passwdtype = propertyMap.find("PasswordMode").value().toInt();
            m_user.uid = propertyMap.find("Uid").value().toInt();
            m_user.autologin = false;
            m_user.objpath = path;

        }
        else
            qDebug() << "reply failed";
    }

}

QString BiometricsWidget::_accountTypeIntToString(int type){
    QString atype;
    if (type == STANDARDUSER)
        atype = tr("Standard");
    else if (type == ADMINISTRATOR)
        atype = tr("Admin");
    else if (type == ROOT)
        atype = tr("root");

    return atype;
}

void BiometricsWidget::showChangePwdDialog()
{
    ChangeUserPwd dialog(m_user.username);
    dialog.exec();
}

bool BiometricsWidget::getBioStatus()
{
    QProcess process;
    process.start("bioctl status");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();
    if (output.contains("enable", Qt::CaseInsensitive)) {
        return true;
    }
    else {
        return false;
    }
}

void BiometricsWidget::setBioStatus(bool status)
{
    enableBiometricBtn->setChecked(true);
}

void BiometricsWidget::onBiometricUSBDeviceHotPlug(int drvid, int action, int deviceNum)
{
    switch(action)
    {
    case ACTION_ATTACHED:
    {
        //插入设备后，需要更新设备列表
        QTimer::singleShot(500, this, [&,this](){
            int savedDeviceId = -1;
            if(this->currentDevice)
                savedDeviceId = this->currentDevice->id;
            this->updateDevice();
            if(savedDeviceId >= 0)
                this->setCurrentDevice(savedDeviceId);
            this->onbiometricDeviceBoxCurrentIndexChanged(this->ui->biometricDeviceBox->currentIndex());
        });
        break;
    }
    case ACTION_DETACHED:
    {
        updateDevice();
    }

    }
}

void BiometricsWidget::onBiometricServiceStatus(bool isActive)
{
    if (isActive) {
        QTimer::singleShot(500, this, [&,this](){
            int savedDeviceId = -1;
            if(this->currentDevice)
                savedDeviceId = this->currentDevice->id;
            this->updateDevice();
            if(savedDeviceId >= 0)
                this->setCurrentDevice(savedDeviceId);
            this->onbiometricDeviceBoxCurrentIndexChanged(this->ui->biometricDeviceBox->currentIndex());
        });
    }
}

void BiometricsWidget::setBiometricDeviceVisible(bool visible)
{
    if( visible && getBioStatus()){
        ui->enableBiometricFrame->setStyleSheet("QFrame{background: palette(base);\
                                            border-top-left-radius: 4px;border-top-right-radius: 4px;}");
        ui->enableBiometricFrame->setMinimumHeight(70);
        ui->enableBiometricFrame->setMaximumHeight(70);
        ui->enableBiometricFrame->setContentsMargins(0,0,0,10);
        ui->biometricTypeFrame->show();
        ui->biometricDeviceFrame->show();
        ui->bioFeatureListWidget->show();
        addBioFeatureBtn->show();
        ui->line1->show();
        ui->line2->show();
        ui->line3->show();
    } else {
        ui->enableBiometricFrame->setStyleSheet("QFrame{background: palette(base);\
                                                    border-radius: 4px;}");
        ui->enableBiometricFrame->setMinimumHeight(60);
        ui->enableBiometricFrame->setMaximumHeight(60);
        ui->enableBiometricFrame->setContentsMargins(0,0,0,0);
        ui->biometricTypeFrame->hide();
        ui->biometricDeviceFrame->hide();
        ui->bioFeatureListWidget->hide();
        addBioFeatureBtn->hide();
        ui->line1->hide();
        ui->line2->hide();
        ui->line3->hide();
    }
}

void BiometricsWidget::updateDevice()
{
    deviceMap.clear();
    DeviceList deviceList = m_biometricProxy->GetDevList();

    QString default_name = GetDefaultDevice(QString(qgetenv("USER")));

    for(auto pDeviceInfo : deviceList)
    {
        deviceMap[pDeviceInfo->deviceType].push_back(pDeviceInfo);
    }
    ui->biometrictypeBox->clear();
//    for(int type : deviceMap.keys())
//    {
//        if (REMOTE_QRCODE_TYPE == type)
//            continue ;
//        ui->biometrictypeBox->addItem(DeviceType::getDeviceType_tr(type), type);
//    }
    for (int type =0; type < 5; type++)
    {
        ui->biometrictypeBox->addItem(DeviceType::getDeviceType_tr(type), type);
    }
    if(deviceMap.size() > 0)
    {
        DeviceInfoPtr ptr = findDeviceByName(default_name);
        if(ptr)
        {
            setCurrentDevice(default_name);
        }else{
            int index = deviceMap.keys().at(0);
            if (deviceMap[index].size() > 0) {
                setCurrentDevice(deviceMap[index].at(0));
            }
        }
    }
}

void BiometricsWidget::setCurrentDevice(int drvid)
{
    DeviceInfoPtr pDeviceInfo = findDeviceById(drvid);
    if(pDeviceInfo)
    {
        setCurrentDevice(pDeviceInfo);
    }
}

void BiometricsWidget::setCurrentDevice(const QString &deviceName)
{
    DeviceInfoPtr pDeviceInfo = findDeviceByName(deviceName);
    if(pDeviceInfo)
    {
        setCurrentDevice(pDeviceInfo);
    }
}

void BiometricsWidget::setCurrentDevice(const DeviceInfoPtr &pDeviceInfo)
{
    this->currentDevice = pDeviceInfo;
    ui->biometrictypeBox->setCurrentText(DeviceType::getDeviceType_tr(pDeviceInfo->deviceType));
    ui->biometricDeviceBox->setCurrentText(pDeviceInfo->shortName);

}

DeviceInfoPtr BiometricsWidget::findDeviceById(int drvid)
{
    for(int type : deviceMap.keys())
    {
        DeviceList &deviceList = deviceMap[type];
        auto iter = std::find_if(deviceList.begin(), deviceList.end(),
                                 [&](DeviceInfoPtr ptr){
            return ptr->id == drvid;
        });
        if(iter != deviceList.end())
        {
            return *iter;
        }
    }
    return DeviceInfoPtr();
}

DeviceInfoPtr BiometricsWidget::findDeviceByName(const QString &name)
{
    for(int type : deviceMap.keys())
    {
        DeviceList &deviceList = deviceMap[type];
        auto iter = std::find_if(deviceList.begin(), deviceList.end(),
                                 [&](DeviceInfoPtr ptr){
            return ptr->shortName == name;
        });
        if(iter != deviceList.end())
        {
            return *iter;
        }
    }
    return DeviceInfoPtr();
}

bool BiometricsWidget::deviceExists(int drvid)
{
    return (findDeviceById(drvid) != nullptr);
}

bool BiometricsWidget::deviceExists(const QString &deviceName)
{
    return (findDeviceByName(deviceName) != nullptr);
}

void BiometricsWidget::onbiometricTypeBoxCurrentIndexChanged(int index)
{
    if(index < 0 /*|| index >= deviceMap.keys().size()*/)
    {
        return;
    }

    int type = ui->biometrictypeBox->itemData(index).toInt();
    ui->biometricDeviceBox->clear();
    int count = 0;
    for(auto &deviceInfo : deviceMap.value(type))
    {
        count++;
        QString default_name = GetDefaultDevice(QString(qgetenv("USER")));
        if(default_name == deviceInfo->shortName) {
            QString defaultText = tr("(default)");
            defaultText = deviceInfo->shortName + "   " + defaultText;
            ui->biometricDeviceBox->addItem(defaultText);
        } else {
            ui->biometricDeviceBox->addItem(deviceInfo->shortName);
        }
    }
    QString addText = tr("Add ") + DeviceType::getDeviceType_tr(type);
    addBioFeatureBtn->setName(addText);
    if(count == 0) {
        ui->biometricDeviceBox->blockSignals(true);
        ui->biometricDeviceBox->addItem(tr("No available device was detected"));
        ui->biometricDeviceBox->blockSignals(false);
        ui->biometricDeviceBox->setDisabled(true);
        addBioFeatureBtn->setDisabled(true);
    } else {
        int index = ui->biometricDeviceBox->findText(tr("No available device was detected"));
        if(index != -1){
            ui->biometricDeviceBox->blockSignals(true);
            ui->biometricDeviceBox->removeItem(index);
            ui->biometricDeviceBox->blockSignals(false);
        }
        ui->biometricDeviceBox->setDisabled(false);
        addBioFeatureBtn->setDisabled(false);
    }
    biometricFeatureMap.clear();
    updateFeatureList();
}

void BiometricsWidget::onbiometricDeviceBoxCurrentIndexChanged(int index)
{
    if(index < 0)
    {
        return;
    }

    int type = ui->biometrictypeBox->currentData().toInt();

    if (!deviceMap.contains(type) || index >= deviceMap.value(type).size())
        return;
    DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index);
    QList<QVariant> args;

    currentDevice = deviceInfo;
    args << QVariant(deviceInfo->id)
        << QVariant((int)getuid()) << QVariant(0) << QVariant(-1);
    serviceInterface->callWithCallback("GetFeatureList", args, this,
                        SLOT(updateFeatureListCallback(QDBusMessage)),
                        SLOT(errorCallback(QDBusError)));
}

void BiometricsWidget::onFeatureChanged(int drvid,int uid,int cType)
{
    if(isShowDialog || isShowEnrollDialog){
        isShowDialog = false;
        return ;
    }

    QTimer::singleShot(200, [&]{
        int savedDeviceId = -1;
        if(currentDevice)
            savedDeviceId = currentDevice->id;

        updateDevice();
        if(savedDeviceId >= 0)
            setCurrentDevice(savedDeviceId);
   });
}

void BiometricsWidget::updateFeatureListCallback(QDBusMessage callbackReply)
{
    QList<QDBusVariant> qlist;
    int listsize;
    QList<QVariant> variantList = callbackReply.arguments();
    listsize = variantList[0].value<int>();
    variantList[1].value<QDBusArgument>() >> qlist;
    if (qlist.size() > 0) {
        //当前设备存在时
        if (currentDevice) {
            FeatureInfoPtr featureInfo0 = std::make_shared<FeatureInfo>();
            qlist[0].variant().value<QDBusArgument>() >> *featureInfo0;
            //如果设备类型相同
            if (currentDevice->deviceType == featureInfo0->biotype) {
                //清除生物特征列表
                ui->bioFeatureListWidget->clear();
                biometricFeatureMap.clear();
                //重新添加生物特征
                for (int i = 0; i < listsize; i++) {
                    FeatureInfoPtr featureInfo = std::make_shared<FeatureInfo>();
                    qlist[i].variant().value<QDBusArgument>() >> *featureInfo;                    
                    addFeature(featureInfo);
                }
            }
        } else {
            ui->bioFeatureListWidget->clear();
            biometricFeatureMap.clear();
            for (int i = 0; i < listsize; i++) {
                FeatureInfoPtr featureInfo = std::make_shared<FeatureInfo>();
                qlist[i].variant().value<QDBusArgument>() >> *featureInfo;
                addFeature(featureInfo);
            }
        }
    } else if (qlist.size() == 0){
        ui->bioFeatureListWidget->clear();
        biometricFeatureMap.clear();
    }
    updateFeatureList();
}

void BiometricsWidget::updateFeatureList()
{
    ui->bioFeatureListWidget->setFixedHeight(biometricFeatureMap.count()*ITEMHEIGH + 1);
}

void BiometricsWidget::errorCallback(QDBusError error)
{

}

void BiometricsWidget::showEnrollDialog()
{
    if(ui->biometricDeviceBox->count() <= 0 || ui->biometrictypeBox->count() <= 0)
        return ;

    int index = ui->biometricDeviceBox->currentIndex();
    int type = ui->biometrictypeBox->currentData().toInt();

    if(index < 0|| type < 0)
        return ;

    DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index);

    if(!deviceInfo)
        return ;

    isShowEnrollDialog = true;
    BiometricEnrollDialog * dialog = new BiometricEnrollDialog(serviceInterface,deviceInfo->deviceType,deviceInfo->id,getuid());
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    //gdxfp显示指纹图片
    if(deviceInfo->shortName == "gdxfp")
        dialog->setProcessed(true);

    if(deviceInfo->deviceType == BIOTYPE_FACE)
        dialog->setIsFace(true);

    int num=1;
    QStringList strList;
    QList<int> idxList;
    if(!m_biometricProxy->getFeatureInfoList(deviceInfo->id, getuid(), strList, idxList)) {
        return ;
    }
    QString featurename;
    int freeIndex = 0;
    while(1){
        featurename = DeviceType::getDeviceType_tr(deviceInfo->deviceType) + QString::number(num);
        if(!strList.contains(featurename))
            break;
        num++;
    }
    num = 0;
    while(1) {
        if (!idxList.contains(num)) {
            freeIndex = num;
            break;
        }
        num ++;
    }
    dialog->enroll(deviceInfo->id,getuid(),freeIndex,featurename);

    onbiometricDeviceBoxCurrentIndexChanged(ui->biometricDeviceBox->currentIndex());
    isShowEnrollDialog = false;
}

void BiometricsWidget::showVerifyDialog(FeatureInfoPtr featureinfo)
{
    DeviceInfoPtr deviceInfoPtr = findDeviceByName(featureinfo->device_shortname);
    if(!deviceInfoPtr)
            return ;

    BiometricEnrollDialog * dialog = new BiometricEnrollDialog(serviceInterface,deviceInfoPtr->deviceType,deviceInfoPtr->id,getuid());
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    if(deviceInfoPtr->shortName == "huawei")
        dialog->setProcessed(true);

    if(deviceInfoPtr->deviceType == BIOTYPE_FACE)
        dialog->setIsFace(true);

    dialog->verify(deviceInfoPtr->id,getuid(),featureinfo->index);
}

void BiometricsWidget::biometricShowMoreInfoDialog()
{
    if(ui->biometricDeviceBox->count() <= 0 || ui->biometrictypeBox->count() <= 0)
        return ;

    int index = ui->biometricDeviceBox->currentIndex();
    int type = ui->biometrictypeBox->currentData().toInt();

    if(index < 0|| type < 0)
        return ;

    DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index);

    if(!deviceInfo)
        return ;

    BiometricMoreInfoDialog * dialog = new BiometricMoreInfoDialog(deviceInfo);
    dialog->exec();
}

void BiometricsWidget::renameFeaturedone(FeatureInfoPtr featureinfo ,QString newname)
{
     QListWidgetItem *item = biometricFeatureMap.value(featureinfo->index_name);
     ui->bioFeatureListWidget->takeItem(ui->bioFeatureListWidget->row(item));
     biometricFeatureMap.remove(featureinfo->index_name);


     featureinfo->index_name = newname;
     addFeature(featureinfo);

}

void BiometricsWidget::deleteFeaturedone(FeatureInfoPtr featureinfo)
{

    QListWidgetItem *item = biometricFeatureMap.value(featureinfo->index_name);

    ui->bioFeatureListWidget->takeItem(ui->bioFeatureListWidget->row(item));
    biometricFeatureMap.remove(featureinfo->index_name);

    updateFeatureList();
}

void BiometricsWidget::addFeature(FeatureInfoPtr &featureinfo)
{
    HoverWidget * baseWidget = new HoverWidget(featureinfo->index_name);
    baseWidget->setMinimumSize(550, 60);
    baseWidget->setMaximumSize(16777215, 60);
    baseWidget->setAttribute(Qt::WA_DeleteOnClose);
    baseWidget->setStyleSheet("HoverWidget{background: palette(base);}\
                              HoverWidget:hover:!pressed{background: palette(base);}");
    //ui->currentUserFrame->setContentsMargins(16,0,16,0);

    QVBoxLayout * baseVerLayout = new QVBoxLayout(baseWidget);
    baseVerLayout->setSpacing(0);
    baseVerLayout->setContentsMargins(0, 0, 0, 0);
    QHBoxLayout * baseHorLayout = new QHBoxLayout();
    baseHorLayout->setSpacing(16);
    baseHorLayout->setContentsMargins(0, 0, 0, 0);

    QFrame * widget = new QFrame(baseWidget);
    widget->setFrameShape(QFrame::Shape::Box);
    widget->setFixedHeight(60);

    QHBoxLayout * mainHorLayout = new QHBoxLayout(widget);
    mainHorLayout->setSpacing(16);
    mainHorLayout->setContentsMargins(10, 0, 16, 0);

    NameLabel *nameLabel = new NameLabel(widget);
    nameLabel->setText(featureinfo->index_name);

    connect(nameLabel, &NameLabel::clicked, this, [&,this,featureinfo](){
        DeviceInfoPtr deviceInfoPtr = findDeviceByName(featureinfo->device_shortname);
        if(!deviceInfoPtr)
                return ;
        QStringList names = m_biometricProxy->getAllFeaturelist(getuid());
        //QStringList names = m_biometricProxy->getFeaturelist(deviceInfoPtr->id,getuid());
        ChangeFeatureName * dialog = new ChangeFeatureName(names);

        dialog->setTitle(ui->biometrictypeBox->currentText());
        connect(dialog, &ChangeFeatureName::sendNewName, [&,this,featureinfo](QString rename){
            if(rename == "" || rename == featureinfo->index_name)
                return;

            DeviceInfoPtr deviceInfoPtr = findDeviceByName(featureinfo->device_shortname);
            if(!deviceInfoPtr)
                    return ;
            bool res = m_biometricProxy->renameFeature(deviceInfoPtr->id,getuid(),featureinfo->index,rename);
            renameFeaturedone(featureinfo,rename);
        });
        dialog->exec();
    });

    mainHorLayout->addWidget(nameLabel);
//    mainHorLayout->addWidget(renameEdit);
    mainHorLayout->addStretch();
//    mainHorLayout->addWidget(renameBtn);
//    mainHorLayout->addWidget(verifyBtn);

    widget->setLayout(mainHorLayout);

    QPushButton * delBtn = new QPushButton(baseWidget);
    delBtn->setProperty("isWindowButton", 0x2);
    delBtn->setProperty("useIconHighlightEffect", 0x8);
    delBtn->setFixedSize(30, 30);
    delBtn->setIconSize(QSize(16, 16));
    delBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));
    delBtn->setFlat(true);
    delBtn->hide();
    connect(delBtn, &QPushButton::clicked, this, [&,this,featureinfo](bool checked){
        Q_UNUSED(checked)
        DeviceInfoPtr deviceInfoPtr = findDeviceByName(featureinfo->device_shortname);
        if(!deviceInfoPtr)
                return ;
        isShowDialog = true;
        bool res = m_biometricProxy->deleteFeature(deviceInfoPtr->id,getuid(),featureinfo->index,featureinfo->index);
        if(!res){
             deleteFeaturedone(featureinfo);
        }
    });

    connect(baseWidget, &HoverWidget::enterWidget, this, [=](QString name){
        Q_UNUSED(name)
//        renameBtn->show();
    //驱动gdxfp不支持验证
//        if(featureinfo->device_shortname != "gdxfp")
//        verifyBtn->show();
        delBtn->show();
    });
    connect(baseWidget, &HoverWidget::leaveWidget, this, [=](QString name){
        Q_UNUSED(name)
//        renameBtn->hide();
//        verifyBtn->hide();
        delBtn->hide();
    });

    baseHorLayout->addWidget(widget);
    baseHorLayout->addWidget(delBtn, Qt::AlignVCenter);
    baseHorLayout->addSpacing(16);

    baseVerLayout->addLayout(baseHorLayout);
    QFrame *line = new QFrame(baseWidget);
    line->setMinimumSize(QSize(550, 1));
    line->setMaximumSize(QSize(16777215, 1));
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    baseWidget->setLayout(baseVerLayout);
    baseVerLayout->addWidget(line);

    QListWidgetItem * item = new QListWidgetItem(ui->bioFeatureListWidget);
    item->setSizeHint(QSize(QSizePolicy::Expanding, ITEMHEIGH));
    item->setData(Qt::UserRole, QVariant(featureinfo->index_name));
    item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
    ui->bioFeatureListWidget->setItemWidget(item, baseWidget);

    biometricFeatureMap.insert(featureinfo->index_name, item);
}

void BiometricsWidget::showQRCodeScanDialog()
{
    // 判断生物识别库是否支持微信扫码
    bool bExistQrCodeModule = false;
    DeviceInfoPtr deviceInfo = nullptr;
    DeviceMap::iterator itDeviceMap = deviceMap.begin();
    for (; itDeviceMap != deviceMap.end(); itDeviceMap ++) {
        for (auto dev : itDeviceMap.value()) {
            if (dev->id == DRIVEID_WECHAT && itDeviceMap.key() == BIOTYPE_WECHAT) {
                bExistQrCodeModule = true;
                deviceInfo = dev;
            }
        }
    }
    if (!bExistQrCodeModule || !deviceInfo) {
        return ;
    }

    QRCodeEnrollDialog * dialog = new QRCodeEnrollDialog(serviceInterface,deviceInfo->deviceType,deviceInfo->id,getuid(), this);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    int num=1;
    QStringList list = m_biometricProxy->getFeaturelist(deviceInfo->id,getuid(),0,-1);
    QString featurename;
    while(1){
        featurename = "qrcode" + QString::number(num);
        if(!list.contains(featurename))
            break;
        num++;
    }
    dialog->enroll(deviceInfo->id,getuid(),-1,featurename);
    dialog->exec();

    QTimer::singleShot(50, this, [&,this](){
        int maxWidth;
        maxWidth = this->ui->qrCodeFrame->width() - 76 - this->ui->qrCodeLoginlabel->width() -
                    ui->boundWechatKey->width() - this->ui->bindOrUnbindBtn->width() - this->ui->boundWechatLabel->width();
        this->ui->qrCodeLoginlabel2->setFixedWidth(maxWidth);
        this->ui->qrCodeLoginlabel2->setText(tr("(Can be used to log in, unlock the system, and authorize authentication)"));
    });

    QTimer::singleShot(0, this, [&,this](){
        Q_EMIT this->updateQRCodeInfo();
    });
}

bool BiometricsWidget::isQRCodeModuleExist()
{
    bool bExistQrCodeModule = false;
    DeviceMap::iterator itDeviceMap = deviceMap.begin();
    for (; itDeviceMap != deviceMap.end(); itDeviceMap ++) {
        for (auto dev : itDeviceMap.value()) {
            if (dev->id == DRIVEID_WECHAT && itDeviceMap.key() == BIOTYPE_WECHAT) {
                bExistQrCodeModule = true;
                break;
            }
        }
    }
    return bExistQrCodeModule;
}

QString BiometricsWidget::getCurUserQRCodeAcount()
{
    DeviceInfoPtr deviceInfo = nullptr;
    DeviceMap::iterator itDeviceMap = deviceMap.begin();
    for (; itDeviceMap != deviceMap.end(); itDeviceMap ++) {
        for (auto dev : itDeviceMap.value()) {
            if (dev->id == DRIVEID_WECHAT && itDeviceMap.key() == BIOTYPE_WECHAT) {
                deviceInfo = dev;
            }
        }
    }
    if (!deviceInfo) {
        return "";
    }
    QStringList list = m_biometricProxy->getFeaturelist(deviceInfo->id,getuid(),0,-1);
    if (list.size() > 0) {
        return list[0];
    } else {
        return "";
    }
}

void BiometricsWidget::onUpdateQRCodeInfo()
{
    m_strBoundWechat = getCurUserQRCodeAcount();
    if (m_strBoundWechat.isEmpty()) {
        this->ui->boundWechatKey->hide();
        this->ui->boundWechatLabel->setText(tr(""));
        this->ui->bindOrUnbindBtn->setText(tr("Binding WeChat"));
    } else {
        this->ui->boundWechatKey->show();
        this->ui->boundWechatLabel->setText(m_strBoundWechat);
        this->ui->bindOrUnbindBtn->setText(tr("Unbind"));
    }
}

void BiometricsWidget::resizeEvent(QResizeEvent *event)
{
    QTimer::singleShot(50, this, [&,this](){
        int maxWidth;
        maxWidth = this->ui->qrCodeFrame->width() - 76 - this->ui->qrCodeLoginlabel->width() -
                    ui->boundWechatKey->width() - this->ui->bindOrUnbindBtn->width() - this->ui->boundWechatLabel->width();
        this->ui->qrCodeLoginlabel2->setFixedWidth(maxWidth);
        this->ui->qrCodeLoginlabel2->setText(tr("(Can be used to log in, unlock the system, and authorize authentication)"));
    });
}

void BiometricsWidget::readConfigures()
{
    QSettings sysSettings(UKUI_BIOMETRIC_SYS_CONFIG_PATH, QSettings::IniFormat);
    sysSettings.beginGroup("Functions");
    if (sysSettings.allKeys().contains("EnableQRCode")) {
        m_isEnabelQRCode = sysSettings.value("EnableQRCode").toBool();
    }
    sysSettings.endGroup();
    Q_EMIT updateFunctionsWidget();
}

void BiometricsWidget::onUpdateFunctionsWidget()
{
    if (m_isEnabelQRCode && isQRCodeModuleExist()) {
        ui->qrCodeFrame->show();
    } else {
        ui->qrCodeFrame->hide();
    }
}

/* 添加搜索索引 */
void BiometricsWidget::initSearchText()
{
    //~ contents_path /Biometrics/Login options
    //~ contents_path /Biometrics/Password
    //~ contents_path /Biometrics/Scan code login
    //~ contents_path /Biometrics/Biometric
    //~ contents_path /Biometrics/Type
    //~ contents_path /Biometrics/Device
}
